Java 8中,Function,Consumer,Predicate,Supplier举例

原文地址:https://my.oschina.net/0sbVMw/blog/535010

Function,Consumer,Predicate,Supplier这些接口有一个共性,就是都有一个@FunctionalInterface的注解, 有了这个注解,你就可以自定义lamda表达式了.

本文先介绍一些例子,然后自定义一个lamda表达式的接口.

先看一下Function接口定义:

    @FunctionalInterface    
    public interface Function<T, R>

接口接受两个泛型类型<T, R>.

再看一下接口定义的方法(非静态,非default), 支持lamda表达式的接口只允许定义一个抽象方法(@FunctionalInterface注解的接口,只允许定义一个抽象方法),只要记住这一点,你就不会弄混了.

    apply(T t);    
    /**
     * T 入参类型, t 输入参数
     * R 返回值类型
     */

OK, 现在明确了, 该接口的lamda表达式应该是接受一个入参,最后要有一个返回值, 写法应该是这样的: (x) -> {return y;} 

如果你的lamda表达式非常简单,只有一行,那么你可以不写return, 不加花括号{}, 返回值后面可以不加分号.

下面就可以写example了, 写一个简单的, 再写一个标准的.

    public void testFunction(){
                //简单的,只有一行
		Function<Integer, Stringfunction1 = (x) -> "test result: " + x;
		
		//标准的,有花括号, return, 分号.
		Function<StringStringfunction2 = (x) -> {
			return "after function1";
		};
		System.out.println(function1.apply(6));
		System.out.println(function1.andThen(function2).apply(6));
	}

OK, Function的例子写完了,接下来写其他的,其实原理懂了,其他的就都简单了,然后就是熟能生巧了.



再看看Supplier的接口定义,这个接口定义比较简单,我就都贴上来了

    @FunctionalInterface
    public interface Supplier<T{

        /**
         * Gets a result.
         *
         * @return a result
         */
        get();
    }

接口接受一个泛型<T>, 接口方法是一个无参数的方法, 有一个类型为T的返回值. OK, 那么接口的lamda表达式应该是这样的: () -> { return something; }, 好,下面来写一个example.

    public void testSupplier(){
                //简写
		Supplier<String> supplier1 = () -> "Test supplier";
		System.out.println(supplier1.get());
		
		//标准格式
		Supplier<Integer> supplier2 = () -> {
			return 20;
		};
		System.out.println(supplier2.get() instanceof Integer);
	}

到这里你或许有一点疑惑, 这Supplier到底能用在哪啊? Java 8里新增了一个异步线程的类,很牛逼,很强大的类: CompletableFuture, 里面的很多方法的入参都用到的Supplier, 例如: supplyAsync方法. 本文暂时不介绍CompletableFuture.



接下来是Consumer, 我们来看一下接口的定义:

    @FunctionalInterface
    public interface Consumer<T>

然后再看一下里面的抽象方法:

    void accept(T t);

现在了解了: 接口接受一个泛型<T>, 接口方法是入参类型为T, 无返回值的方法, OK,下面开始写example:

    public void testConsumer(){
		Consumer<String> consumer1 = (x) -> System.out.print(x);
		Consumer<String> consumer2 = (x) -> {
			System.out.println(" after consumer 1");
		};
		consumer1.andThen(consumer2).accept("test consumer1");
	}



接下来看一下Predicate接口

接口定义:

    @FunctionalInterface    
    public interface Predicate<T>

抽象方法:

    boolean test(T t);

接口接受一个泛型<T>, 接口方法的入参类型是T, 返回值是一个布尔值, OK, 下面写example:

    public void testPredicate(){
		Predicate<String> predicate = (x) -> x.length() > 0;
		System.out.println(predicate.test("String"));
	}

Predicate接口在stream里面用的比较多, 感兴趣的可以去看看stream, java 8 里另一个新的东西,很好玩.




到这里基本明白这些lamda表达式的接口怎么用了,接下来自定义一个支持lamda表达式的接口玩玩,

    @FunctionalInterface    
    public interface CustomLamda<T{
    
    	testCustomFunction(Consumer<T> cunsumer);
    	
    	/*如果把下面方法的注释放开, 那么接口就报错了. 验证了前面所说的:@FunctionalInterface注解的接口只允许         *有一个抽象方法
    	 */
        //T anErrorMethod();
    }

下面是实现:

    public void testCustomLamda(){
		Consumer<String> consumer = (x) -> {
			System.out.println("test" + x);
		};
		CustomLamda<String> customLamda = (x) -> {
			x.accept("6");
			return "6";
		};
		customLamda.testCustomFunction(consumer);
	}

本文仅仅是抛砖引玉, 深入的东西还需要多读多看.

以下是一个演示 Java SupplierPredicateFunction<T, R> 的例子: ```java import java.util.ArrayList; import java.util.List; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; public class Demo { public static void main(String[] args) { // 使用 Supplier 创建一个返回字符串的函数 Supplier<String> supplier = () -> "Hello, World!"; // 使用 Predicate 过滤字符串列表的元素 List<String> list = new ArrayList<>(); list.add("Hello"); list.add("World"); list.add("Java"); Predicate<String> predicate = s -> s.length() > 4; List<String> filteredList = filterList(list, predicate); // 使用 Function 将字符串转换为大写形式 Function<String, String> function = String::toUpperCase; List<String> upperCaseList = mapList(filteredList, function); // 打印结果 System.out.println(supplier.get()); System.out.println(filteredList); System.out.println(upperCaseList); } // 过滤列表符合条件的元素 public static <T> List<T> filterList(List<T> list, Predicate<T> predicate) { List<T> resultList = new ArrayList<>(); for (T t : list) { if (predicate.test(t)) { resultList.add(t); } } return resultList; } // 对列表的每个元素应用函数 public static <T, R> List<R> mapList(List<T> list, Function<T, R> function) { List<R> resultList = new ArrayList<>(); for (T t : list) { R result = function.apply(t); resultList.add(result); } return resultList; } } ``` 在上面的例子,我们使用 Java Supplier 创建了一个返回字符串的函数,使用 Predicate 过滤了一个字符串列表的元素,并使用 Function 将列表的每个元素转换为大写形式。具体来说,我们: 1. 使用 Supplier 创建了一个返回字符串 "Hello, World!" 的函数; 2. 创建了一个包含三个字符串的列表,并使用 Predicate 过滤掉其长度小于等于 4 的元素; 3. 使用 Function 将过滤后的列表的每个元素转换为大写形式; 4. 打印结果。 输出结果如下: ``` Hello, World! [World, Java] [WORLD, JAVA] ``` 需要注意的是,我们在示例使用了泛型方法 `filterList` 和 `mapList`,它们可以接受任何类型的列表和函数,并返回相应类型的结果列表。这种方式可以使代码更加通用和灵活。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值